package controllers

import (
	"net/http"
	"strconv"
	"time"

	"gitee.com/golanglearn/small/app"
	"gitee.com/golanglearn/small/models"
	"gitee.com/golanglearn/small/repositories"
	"gitee.com/golanglearn/small/services"

	"github.com/gorilla/mux"
)

type SubTaskController struct {
	*app.App
	repositories.SubTaskRepository
	repositories.TaskRepository
	repositories.UserRepository
}

func NewSubTaskController(a *app.App, str repositories.SubTaskRepository, tr repositories.TaskRepository, ur repositories.UserRepository) *SubTaskController {
	return &SubTaskController{a, str, tr, ur}
}

func (stc *SubTaskController) GetByTid(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	tid, err := strconv.Atoi(vars["tid"])
	if err != nil {
		NewAPIError(&APIError{false, "Invalid request", http.StatusBadRequest}, w)
		return
	}
	subtask, err := stc.SubTaskRepository.FindByTid(tid)
	if err != nil {
		NewAPIError(&APIError{false, "Could not find subtask", http.StatusNotFound}, w)
		return
	}

	NewAPIResponse(&APIResponse{Success: true, Data: subtask}, w, http.StatusOK)
}

func (stc *SubTaskController) Create(w http.ResponseWriter, r *http.Request) {

	uid, err := services.UserIdFromContext(r.Context())
	if err != nil {
		NewAPIError(&APIError{false, "Something went wrong", http.StatusInternalServerError}, w)
		return
	}

	vars := mux.Vars(r)
	tid, err := strconv.Atoi(vars["tid"])
	if err != nil {
		NewAPIError(&APIError{false, "Invalid request", http.StatusBadRequest}, w)
		return
	}

	_, err = stc.SubTaskRepository.FindByTid(tid)
	if err == nil {
		NewAPIError(&APIError{false, "Create only one subtask", http.StatusBadRequest}, w)
		return
	}

	subtask := &models.SubTask{
		TID:       tid,
		UID:       uid,
		CreatedAt: time.Now(),
	}

	err = stc.SubTaskRepository.Create(subtask)
	if err != nil {
		NewAPIError(&APIError{false, "Could not create subtask", http.StatusBadRequest}, w)
		return
	}

	u, err := stc.UserRepository.FindById(uid)
	if err != nil {
		NewAPIError(&APIError{false, "Content is required", http.StatusBadRequest}, w)
		return
	}
	subtask.Executor = u.Name

	defer r.Body.Close()
	NewAPIResponse(&APIResponse{Success: true, Message: "Task created", Data: subtask}, w, http.StatusOK)
}

func (stc *SubTaskController) Delete(w http.ResponseWriter, r *http.Request) {
	uid, err := services.UserIdFromContext(r.Context())
	if err != nil {
		NewAPIError(&APIError{false, "Something went wrong", http.StatusInternalServerError}, w)
		return
	}

	vars := mux.Vars(r)
	tid, err := strconv.Atoi(vars["tid"])
	if err != nil {
		NewAPIError(&APIError{false, "Invalid request", http.StatusBadRequest}, w)
		return
	}

	task, err := stc.TaskRepository.FindByTid(tid)
	if err == nil && task != nil {
		NewAPIError(&APIError{false, "Could not delete subtask, the task has been generated", http.StatusBadRequest}, w)
		return
	}

	subtask, err := stc.SubTaskRepository.FindById(uid, tid)
	if err == nil && uid != subtask.UID {
		NewAPIError(&APIError{false, "Could not delete subtask, must be himself", http.StatusBadRequest}, w)
		return
	}

	err = stc.SubTaskRepository.Delete(uid, tid)
	if err != nil {
		NewAPIError(&APIError{false, "Could not delete subtask", http.StatusBadRequest}, w)
		return
	}

	NewAPIResponse(&APIResponse{Success: true, Message: "Subtask deleted", Data: subtask}, w, http.StatusOK)
}
